﻿// FindCircleDlg.cpp: 实现文件
//

#include "stdafx.h"
#include "MultPointCalibration.h"
#include "FindCircleDlg.h"
#include "afxdialogex.h"

// FindCircleDlg 对话框

IMPLEMENT_DYNAMIC(FindCircleDlg, CDialogEx)

FindCircleDlg::FindCircleDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_FindCircleDlg, pParent)
{
	
}

FindCircleDlg::~FindCircleDlg()
{
}



long FindCircleDlg::GetROI(SciROI& roi)
{
	SciPoint centerPoint;
	double innerRadius;
	double outerRadius;
	double startAngle;
	double spanAngle;
	FCP.ROI.GetTorus(&centerPoint,&innerRadius,&outerRadius,&startAngle,&spanAngle);
	roi.GenTorus(centerPoint,innerRadius,outerRadius,startAngle,spanAngle);
	return 0;
}

void FindCircleDlg::UpdateDlgParams()
{
#pragma region //! combobox控件

	if (FCP.edgeDirection == SciCircleEdgeDirection::SCI_FINDCIRCLE_INNER_TO_OUTER)
	{
		cmbEdgeDirection.SetCurSel(0);
	}
	else
	{
		cmbEdgeDirection.SetCurSel(1);
	}

	if (FCP.edgePolarity == SciEdgePolarity::SCI_TYPE_BRIGHT_TO_DARK)
	{
		cmbEdgePolarity.SetCurSel(0);
	}
	else if (FCP.edgePolarity == SciEdgePolarity::SCI_TYPE_DARK_TO_BRIGHT)
	{
		cmbEdgePolarity.SetCurSel(1);
	}
	else
	{
		cmbEdgePolarity.SetCurSel(2);
	}

	if (FCP.edgeType == SciEdgeType::SCI_TYPE_FIRST_EDGE)
	{
		cmbEdgeType.SetCurSel(0);
	}
	else if (FCP.edgeType == SciEdgeType::SCI_TYPE_LAST_EDGE)
	{
		cmbEdgeType.SetCurSel(1);
	}
	else
	{
		cmbEdgeType.SetCurSel(2);
	}


#pragma endregion

#pragma region edit控件
	SetDlgItemInt(IDC_EDITEDGESTRENTH,FCP.minEdgeStrength,false);
	SetDlgItemInt(IDC_EDITSERACHLINES, FCP.searchLineCount,false);
#pragma endregion

}

void FindCircleDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_CMBEDGEDIRECTION, cmbEdgeDirection);
	DDX_Control(pDX, IDC_CMBEDGEPOlARITY, cmbEdgePolarity);
	DDX_Control(pDX, IDC_CMBEDGETYPE, cmbEdgeType);
}

long FindCircleDlg::SetParam(SciCircleEdgeDirection edgeDirection, SciEdgeType edgeType, SciEdgePolarity edgePolarity, int minEdgeStrength, int searchLineCount)
{
	/*++++++++++++++++++++++++++++
	** 外部保存的数据设置到对话框的参数
	+++++++++++++++++++++++++++++++
	*/
	return 0;
}

long FindCircleDlg::GetParam(SciCircleEdgeDirection edgeDirection, SciEdgeType edgeType, SciEdgePolarity edgePolarity, int minEdgeStrength, int searchLineCount)
{
	/*++++++++++++++++++++++++++++
	** 当外部需要保存自定义窗口参数时，编写这个函数
	+++++++++++++++++++++++++++++++
	*/
	return 0;
}


BEGIN_MESSAGE_MAP(FindCircleDlg, CDialogEx)
	ON_BN_CLICKED(IDOK, &FindCircleDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDC_BTNEXECUTECIRCLE, &FindCircleDlg::OnBnClickedBtnexecutecircle)
	ON_MESSAGE(WM_SIZE_CHANGED_SHAPE,&FindCircleDlg::OnMoveROI)
END_MESSAGE_MAP()


// FindCircleDlg 消息处理程序


long FindCircleDlg::Execute(SciImage& image,SciROI& ROI ,SciPoint* circleCenter, float* circleRadius)
{
	//删减输出
	SciPointArray pointArray;
	SciPointArray effectivePoints;
	SciPointArray rejectPoints;
	int isFindOK = m_FindCircle.FindCircle(image,
		ROI,
		FCP.Region,
		FCP.edgeDirection,
		FCP.edgePolarity,
		FCP.edgeType,
		FCP.minEdgeStrength,
		FCP.searchLineCount,
		FCP.rejectRatio,
		FCP.edgeWidth,
		FCP.projectionWidth,
		&pointArray,
		&effectivePoints,
		&rejectPoints,
		circleCenter,
		circleRadius);
	return isFindOK;
}

BOOL FindCircleDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	cmbEdgeDirection.Clear();
	cmbEdgeDirection.AddString(L"由里到外");
	cmbEdgeDirection.AddString(L"由外到里");

	cmbEdgePolarity.Clear();
	cmbEdgePolarity.AddString(L"由白到黑");
	cmbEdgePolarity.AddString(L"由黑到白");
	cmbEdgePolarity.AddString(L"所有");

	cmbEdgeType.Clear();
	cmbEdgeType.AddString(L"第一条边缘");
	cmbEdgeType.AddString(L"最后一条边缘");
	cmbEdgeType.AddString(L"所有");

	UpdateDlgParams();

	//! +++++++++++++++++++++++++++++
	//  SCI窗口控件创建
	CStatic* pStaticWnd = (CStatic*)GetDlgItem(IDC_IMG_WND);
	RECT rcParentWnd = { 0 };
	pStaticWnd->GetWindowRect(&rcParentWnd);
	ScreenToClient(&rcParentWnd);
	int lret = SciCreateImageWnd((long)m_hWnd,
		rcParentWnd.left,
		rcParentWnd.top,
		rcParentWnd.right,
		rcParentWnd.bottom,
		&m_SciWnd);
	//对指定按钮设置可见性
	SciSetToolbarVisible(m_SciWnd, SCI_BTN_ALL, false);
	SciSetToolbarVisible(m_SciWnd, SCI_BTN_LOADIMG, true);
	SciSetToolbarVisible(m_SciWnd, SCI_BTN_ZOOMINIMG, true);
	SciSetToolbarVisible(m_SciWnd, SCI_BTN_ZOOMOUTIMG, true);
	SciSetToolbarVisible(m_SciWnd, SCI_BTN_FITIMG, true);
	SciSetToolbarVisible(m_SciWnd, SCI_BTN_DRAWANNULAR, true);

	SciEnableMoveStaticOverlay(m_SciWnd,false);
	SciSetPen(m_SciWnd,0,0,255,1);
	SciDisplayImage(m_SciWnd, srcImage);
	SciRefresh(m_SciWnd);
	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}


void FindCircleDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
#pragma region 界面参数存放到类成员变量中
	UpdateData(true);
	if (cmbEdgeDirection.GetCurSel() == 0)
	{
		FCP.edgeDirection = SciCircleEdgeDirection::SCI_FINDCIRCLE_INNER_TO_OUTER;

	}
	else
	{
		FCP.edgeDirection = SciCircleEdgeDirection::SCI_FINDCIRCLE_OUTER_TO_INNER;
	}

	if (cmbEdgePolarity.GetCurSel() == 0)
	{
		FCP.edgePolarity = SciEdgePolarity::SCI_TYPE_BRIGHT_TO_DARK;

	}
	else if (cmbEdgePolarity.GetCurSel() == 1)
	{
		FCP.edgePolarity = SciEdgePolarity::SCI_TYPE_DARK_TO_BRIGHT;

	}
	else
	{
		FCP.edgePolarity = SciEdgePolarity::SCI_TYPE_ALL;
	}

	if (cmbEdgeType.GetCurSel() == 0)
	{
		FCP.edgeType = SciEdgeType::SCI_TYPE_FIRST_EDGE;

	}
	else if (cmbEdgeType.GetCurSel() == 1)
	{

		FCP.edgeType = SciEdgeType::SCI_TYPE_LAST_EDGE;
	}
	else
	{
		FCP.edgeType = SciEdgeType::SCI_TYPE_BEST_EDGE;
	}

	FCP.minEdgeStrength = GetDlgItemInt(IDC_EDITEDGESTRENTH, NULL, false);
	FCP.searchLineCount = GetDlgItemInt(IDC_EDITSERACHLINES, NULL, false);
#pragma endregion
	
	CDialogEx::OnOK();
}

LRESULT FindCircleDlg::OnMoveROI(WPARAM wParam, LPARAM lParam)
{
	long ROIID = (long)wParam;
	SciGetROI(m_SciWnd,ROIID,&FCP.ROI);
	return LRESULT(0);
}


void FindCircleDlg::OnBnClickedBtnexecutecircle()
{
	// TODO: 在此添加控件通知处理程序代码
	FindCircleParam fcp;
#pragma region 界面参数存放到局部变量中
	fcp.ROI = FCP.ROI;

	if (cmbEdgeDirection.GetCurSel() == 0)
	{
		fcp.edgeDirection = SciCircleEdgeDirection::SCI_FINDCIRCLE_INNER_TO_OUTER;

	}
	else
	{
		fcp.edgeDirection = SciCircleEdgeDirection::SCI_FINDCIRCLE_OUTER_TO_INNER;
	}

	if (cmbEdgePolarity.GetCurSel() == 0)
	{
		fcp.edgePolarity = SciEdgePolarity::SCI_TYPE_BRIGHT_TO_DARK;

	}
	else if (cmbEdgePolarity.GetCurSel() == 1)
	{
		fcp.edgePolarity = SciEdgePolarity::SCI_TYPE_DARK_TO_BRIGHT;

	}
	else
	{
		fcp.edgePolarity = SciEdgePolarity::SCI_TYPE_ALL;
	}

	if (cmbEdgeType.GetCurSel() == 0)
	{
		fcp.edgeType = SciEdgeType::SCI_TYPE_FIRST_EDGE;

	}
	else if (cmbEdgeType.GetCurSel() == 1)
	{

		fcp.edgeType = SciEdgeType::SCI_TYPE_LAST_EDGE;
	}
	else
	{
		fcp.edgeType = SciEdgeType::SCI_TYPE_BEST_EDGE;
	}

	fcp.minEdgeStrength = GetDlgItemInt(IDC_EDITEDGESTRENTH, NULL, false);
	fcp.searchLineCount = GetDlgItemInt(IDC_EDITSERACHLINES, NULL, false);
#pragma endregion
	if (srcImage.Width() == 0)
	{
		MessageBox(L"输入图像为空");
		return;
	}
	SciPointArray pointArray;
	SciPointArray effecttivePoints;
	SciPointArray rejectPoints;
	SciPoint circleCenter;
	float circleRadius;
	
	int isFindOK = m_FindCircle.FindCircle(srcImage,
						fcp.ROI,
						fcp.Region,
						fcp.edgeDirection,
						fcp.edgePolarity,
						fcp.edgeType,
						fcp.minEdgeStrength,
						fcp.searchLineCount,
						fcp.rejectRatio,
						fcp.edgeWidth,
						fcp.projectionWidth,
						&pointArray,
						&effecttivePoints,
						&rejectPoints,
						&circleCenter,
						&circleRadius);
	if (isFindOK == 0)
	{
		CString temp;
		temp.Format(L"%0.3f",circleCenter.x);
		SetDlgItemText(IDC_EDITCENTERX,temp);
		temp = "";
		temp.Format(L"%0.3f",circleCenter.y);
		SetDlgItemText(IDC_EDITCENTERY,temp);
		temp = "";
		temp.Format(L"%0.3f",circleRadius);
		SetDlgItemText(IDC_EDITRADIUS,temp);
		
		//! 显示圆
		SciClearAllOverlay(m_SciWnd);
		SciSetPen(m_SciWnd,0,255,0,3);
		SciOverlay overlay;
		overlay.GenCircle(circleCenter,circleRadius);
		SciDrawStaticOverlay(m_SciWnd,overlay);
		SciRefresh(m_SciWnd);

		SciSetPen(m_SciWnd,0,0,255,2);
		//! 拟合圆 根据点集得到圆心
		//m_FindCircle.FitCircle(pointArray, fcp.rejectRatio, &circleCenter, &circleRadius);
	}
	else
	{
		MessageBox(L"执行找圆失败");
	}
}

INT_PTR FindCircleDlg::DoModal(SciImage& image)
{
	if (image.Width() == 0)
	{
		MessageBox(L"输入图像为空");
		return -1;
	}
	else
	{
		srcImage = image;
	
	}
	return CDialogEx::DoModal();
}


INT_PTR FindCircleDlg::DoModal()
{
	// TODO: 在此添加专用代码和/或调用基类

	return CDialogEx::DoModal();
}
